home *** CD-ROM | disk | FTP | other *** search
- {@@@@@@@@@@@ copyright (C) 1984 by Neil J. Rubenking @@@@@@@@@@@@@@@@@@@@@@@@
- The purchaser of these procedures and functions may include them in COMPILED
- programs freely, but may not sell or give away the source text.
- sidesectortrack
-
- This program uses a number of the procedures on this disk to
- find, change, or create a volume label. You might think you
- could simply FIND it with Find_First (from GETFILE.LIB) and
- change it with a simple RENAME, or create a new file and set
- its attribute to 8 (= Volume label) with FileAttribute (found
- in FILEATTR.LIB. It ain't that easy! The only one of the
- routines I just mentioned that will work is Find_First--the
- others are deeply protected agains acting on the LABEL
-
- This being the case, we seek the label by directly reading
- and writing the directory sectors. It ain't elegant, but
- it does the job.
- }
-
- {$I regpack.typ}
- {$I disktyp.lib}
- {$I grfxtabl.lib}
- {$I titles.lib}
-
- type
- Label_type = string[11];
- directory_entry = record
- name : array[1..11] of char; { See the DOS 2.0 }
- attribute : byte; { Manual, Appendix }
- junk1 : array[1..10] of byte; { C, for description }
- time : array[1..2] of byte; { of directory. But }
- date : array[1..2] of byte; { don't look in the }
- junk2 : array[1..6] of byte; { 2.1 Manual--they }
- end; { took a lot of good }
- buffer_type = array[1..16] of directory_entry; { stuff out! }
- sector_loc = record
- side, sector, track : byte;
- end;
-
- var
- buffer : buffer_type;
- drive : char;
- label_sector, which_entry, free_sector, free_entry : byte;
- N, M, P, error_return, attrib : byte;
- the_label, new_label : label_type;
- dir_sectors : array[1..7] of sector_loc;
-
- {$I getsectr.lib}
- var
- OKAY, found : boolean;
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- procedure DirectoryMap; { This procedure checks what kind }
- begin { of disk we're looking at and }
- for N := 1 to 7 do { locates the sectors that contain }
- with dir_sectors[N] do { the directory. }
- side := 2;
- case disktype(drive) of
- 160: begin
- for N := 1 to 4 do
- with dir_sectors[N] do
- begin
- side := 0;
- track := 0;
- sector := 3+N;
- end;
- end;
- 180: begin
- for N := 1 to 4 do
- with dir_sectors[N] do
- begin
- side := 0;
- track := 0;
- sector := 5+N;
- end;
- end;
- 320: begin
- for N := 1 to 5 do
- with dir_sectors[N] do
- begin
- side := 0;
- track := 0;
- sector := 3+N;
- end;
- for N := 6 to 7 do
- with dir_sectors[N] do
- begin
- side := 1;
- track := 0;
- sector := N-5;
- end;
- end;
- 360: begin
- for N := 1 to 4 do
- with dir_sectors[N] do
- begin
- side := 0;
- track := 0;
- sector := 5+N;
- end;
- for N := 5 to 7 do
- with dir_sectors[N] do
- begin
- side := 1;
- track := 0;
- sector := N-4;
- end;
- end;
- else
- WriteLn('Non-standard format. Halting program');
- HALT;
- end; {case}
- end; {procedure}
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- procedure FindLabel;
- begin
- N := 0;
- Free_entry := 0;
- found := false;
- repeat
- N := N + 1;
- if dir_sectors[N].side < 2 then {if side = 2 here, it means we've
- run out of sectors on a single-
- sided disk}
- begin
- with dir_sectors[N] do
- begin
- GetSector('R',drive,side,sector,track,OKAY);
- { GetSector dumps a sector into
- the buffer. Because the buffer
- is "shaped" like a directory, we
- have instant access to the dir-
- ectory information }
- end;
- if OKAY then
- begin
- for M := 1 to 16 do
- begin
- with buffer[M] do
- begin
- if ((name[1] = #0) or (name[1] = #229))
- and (Free_Entry = 0) then { Note the first free }
- begin { entry--a never-used }
- Free_Entry := M; { one starts w/ chr(0), }
- Free_Sector := N; { an erased one, with }
- end; { chr(229) }
- if attribute = 8 then
- begin { Attribute = 8 means we have }
- Label_sector := N; { found the label. }
- which_entry := M;
- found := true;
- the_label := '';
- for P := 1 to 11 do
- the_label := the_label + name[P];
- end;
- end;
- end;
- end
- else writeLn('Not OKAY!');
- end;
- until found or (not OKAY) or (dir_sectors[N].side = 2) or (N = 7);
- end;
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- procedure WriteNewLabel;
- begin
- new_label[length(new_label)+1] := #0;
- for P := 1 to 11 do
- buffer[which_entry].name[P] := new_label[P];
- with dir_sectors[label_sector] do
- GetSector('W',drive,side,sector,track,OKAY);
- if OKAY then
- WriteLn('Sucessfully changed label of drive ',drive,' to ',new_label)
- else
- WriteLn('Not OKAY!');
- end;
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- procedure CreateLabel;
- var
- registers : regpack;
- {=================================================}
- procedure GetTime(VAR Byt1,Byt2: byte);
- var
- hours, mins, twoSecs : byte; { The DOS TIME function delivers }
- begin { hours, minutes and seconds in }
- registers.AX := $2C shl 8; { one format, but the time info }
- MSDOS(registers); { in the directory is formatted }
- with registers do { quite differently. The point }
- begin { of all the manipulation and }
- hours := CX shr 8; { shifting left and right is to }
- mins := CX and $00FF; { get the time info into this }
- twoSecs := DX shr 9; { shape: }
- end; { || }
- { \/ }
- { high byte low byte }
- {bit # 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 }
- { | h h h h h | m m m m m m | s s s s s | }
- { | hour | minutes | 2-seconds | }
-
- byt2 := (hours shl 3) + (mins shr 3);
- byt1 := ((mins and 7) shl 5) + twoSecs;
- end;
- {=================================================}
- procedure GetDate(VAR Byt1,Byt2: byte);
- var
- month, day : byte;
- year : integer;
- begin
- registers.AX := $2A shl 8;
- MSDOS(registers);
- with registers do
- begin
- year := CX;
- month := DX shr 8;
- day := DX and $00FF;
- end;
-
- { The date information in the directory entry is also in an odd format. }
-
- { high byte low byte }
- {bit # 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 }
- { | y y y y y y y | m m m m | d d d d d | }
- { | year - 1980 | month (1-12) | day (1-31) | }
-
- Byt2 := (((Year - 1980) and $00FF) shl 1) + (month shr 3);
- Byt1 := ((month and 7) shl 5) + day;
- end;
- {=================================================}
- begin
- WriteLn('Diskette in drive ',drive,' has no label.');
- new_label := '';
- Write('Enter label, or just <return> to quit :');
- ReadLn(new_label);
- if new_label <> '' then
- begin
- with dir_sectors[Free_sector] do { Get the sector with }
- GetSector('R',drive,side,sector,track,OKAY); { the first free entry }
- if OKAY then { back into the buffer }
- begin
- with buffer[Free_Entry] do
- begin
- for N := 1 to length(new_label) do
- name[N] := new_label[N];
- if length(new_label) < 11 then
- for N := length(new_label)+1 to 11 do
- name[N] := ' ';
- attribute := 8;
- for N := 1 to 10 do Junk1[N] := 0;
- GetTime(time[1],time[2]);
- GetDate(date[1],date[2]);
- for N := 1 to 6 do Junk2[N] := 0;
- end; {with}
- with dir_sectors[Free_sector] do
- GetSector('W',drive,side,sector,track,OKAY);
- if OKAY then
- WriteLn('Sucessfully created label ',new_label,' for drive ',drive);
- end; { if OKAY}
- end; {if not = ''}
- end;
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- begin
- MakeTitle('LABEL',1); { This procedure is in TITLES.LIB }
- window(1,10,80,25);
- ClrScr;
- repeat
- gotoXY(1,WhereY); ClrEOL;
- Write('Which drive? ');
- Read(drive);
- drive := UpCase(drive);
- until drive in ['A'..'D'];
- WriteLn;
- DirectoryMap;
- FindLabel;
- if found then
- begin
- WriteLn('Current label is ',the_label);
- new_label := '';
- Write('Enter new label, or <return> to leave alone: ');
- readLn(new_label);
- if new_label <> '' then WriteNewLabel;
- end
- else CreateLabel;
- end.